package com.zmn.plat.services.impl.product.productgroup;

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.zmn.manager.mq.interfaces.ZmnMQSender;
import com.zmn.plat.constant.MessageQueueConstant;
import com.zmn.plat.model.mq.ProductGroupMessage;
import com.zmn.plat.model.vo.product.productgroup.ProductGroupVO;
import org.springframework.stereotype.Service;

import com.zmn.common.dto.StatusDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.dictionary.PlatErrorCodeDict;
import com.zmn.plat.common.exception.PlatException;
import com.zmn.plat.model.entity.product.productgroup.ProductGroup;
import com.zmn.plat.model.entity.product.productgroup.ProductGroupQuery;
import com.zmn.plat.persistence.interfaces.product.productgroup.ProductGroupDAO;
import com.zmn.plat.services.interfaces.product.productgroup.ProductGroupService;

import lombok.extern.slf4j.Slf4j;

/**
 * 描述: 产品组基础接口实现类
 *
 * @author tanghongjun
 * @since 2020-08-19 11:18:36
 **/
@Slf4j
@Service
public class ProductGroupServiceImpl implements ProductGroupService {

    private static final String TAG = "产品组基础服务接口";

    @Resource
    private ProductGroupDAO productGroupDao;

    @Resource
    ZmnMQSender zmnMQSender;

    @NacosValue(value = "${spring.mq.topic}", autoRefreshed = true)
    String topic;

    /**
     * 描述: 根据id查询数据
     *
     * @param groupId id
     * @author tanghongjun
     * @since 2020-08-19 11:18:36
     **/
    @Override
    public ProductGroup findById(Integer groupId) {

        if (Objects.isNull(groupId)) {
            log.error("[{}],根据id查询数据groupId为null", TAG);
            return null;
        }
        return productGroupDao.findById(groupId);
    }

    @Override
    public Integer findMaxGropCode() {
        return productGroupDao.findMaxGropCode();
    }

    @Override
    public List<ProductGroup> listByIdList(List<Integer> groupIdList) {
        if (CollectionUtil.isNullOrEmpty(groupIdList)) {
            log.error("nameList null error, groupIdList:{}", groupIdList);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL, "产品组ID集合不能为空");
        }

        return productGroupDao.listByIdList(groupIdList);
    }

    @Override
    public List<ProductGroup> listByNameListAndBizType(Integer bizType, List<String> nameList) throws PlatException {
        if (NumberUtil.isNullOrZero(bizType)) {
            log.error("bizType null error, bizType:{}", bizType);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL, "业务类型不能为空");
        }

        if (bizType < ProductConsts.BIZ_TYPE_C || bizType > ProductConsts.BIZ_TYPE_B) {
            log.error("bizType out of range error, bizType:{},errorCode:{}", bizType, PlatErrorCodeDict.ERROR_CODE_PARAM_OUT_OF_RANGE_ERROR);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PARAM_OUT_OF_RANGE_ERROR, "业务类型取值超出范围");
        }

        if (CollectionUtil.isNullOrEmpty(nameList)) {
            log.error("nameList null error, nameList:{},errorCode:{}", nameList, PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL, "产品组名称不能为空");
        }

        return productGroupDao.listByNameListAndBizType(bizType, nameList);
    }

    @Override
    public List<Integer> listProductGroupIdByBusinessLine(List<Integer> bizLines) {
        if (CollectionUtil.isNullOrEmpty(bizLines)) {
            log.error("bizLines null error, nameList:{},errorCode:{}", bizLines, PlatErrorCodeDict.ERROR_CODE_PANAM_NULL);
            throw new PlatException(PlatErrorCodeDict.ERROR_CODE_PANAM_NULL, "业务线id不能为空");
        }
        return productGroupDao.listProductGroupIdByBusinessLine(bizLines);
    }

    /**
     * 描述: 按条件查询数据 支持分页
     *
     * @param query 查询对象
     * @author tanghongjun
     * @since 2020-08-19 11:18:36
     **/
    @Override
    public List<ProductGroupVO> listPageByQuery(ProductGroupQuery query) {

        if (Objects.isNull(query)) {
            log.error("[{}],按条件查询数据,query为null", TAG);
            return null;
        }

        int count = this.countByQuery(query);
        query.setTotalCount(count);

        return productGroupDao.listPageByQuery(query);
    }

    /**
     * 描述: 按条件查询数据 不支持分页
     *
     * @param query 查询对象
     * @author tanghongjun
     * @since 2020-08-19 11:18:36
     **/
    @Override
    public List<ProductGroup> listByQuery(ProductGroupQuery query) {

        if (Objects.isNull(query)) {
            log.error("[{}],按条件查询数据,query为null", TAG);
            return null;
        }
        return productGroupDao.listByQuery(query);
    }

    @Override
    public List<ProductGroupVO> listTreeByStatus(Integer status) {
        if (Objects.isNull(status)) {
            log.error("[{}],按条件查询数据,status为null", TAG);
            return null;
        }
        return productGroupDao.listTreeByStatus(status);
    }

    /**
     * 描述: 按条件查询数据 不支持分页
     *
     * @param query 查询对象
     * @author tanghongjun
     * @since 2020-08-19 11:18:36
     **/
    @Override
    public Integer countByQuery(ProductGroupQuery query) {

        if (Objects.isNull(query)) {
            log.error("[{}],按条件统计数据,query为null", TAG);
            return null;
        }
        return productGroupDao.countByQuery(query);
    }

    @Override
    public void updateSortByKey(Integer groupId, Integer sort, String updater) {
        ProductGroup productGroup = new ProductGroup();
        productGroup.setGroupId(groupId);
        productGroup.setSort(sort);
        productGroup.setUpdater(updater);
        productGroup.setUpdateTime(DateUtil.getNow());
        productGroupDao.updateSortByKey(productGroup);
    }

    /**
     * 描述: 根据id修改数据 id为必传
     *
     * @param productGroup 待修改数据
     * @return java.lang.Integer
     * @author tanghongjun
     * @since 2020-08-19 11:18:36
     **/
    @Override
    public Integer updateByKey(ProductGroup productGroup) {

        if (Objects.isNull(productGroup.getGroupId())) {
            log.error("[{}],根据id修改数据,productGroup为null", TAG);
            return null;
        }
        Integer result = productGroupDao.updateByKey(productGroup);
        sendProductGroupChange(getProductGroupList(productGroup));
        return result;
    }

    @Override
    public Integer updateReimbursementAmountByKey(Integer groupId, Integer reimbursementAmount,
                                                  String mcStaffRealName) {

        ProductGroup productGroup = productGroupDao.findById(groupId);
        if (Objects.isNull(productGroup)) {
            log.error("[{}],根据id修改数据,productGroup为null", TAG);
            throw new PlatException("修改产品组报销金额失败!无效的groupId");
        }
        productGroup.setReimbursementAmount(reimbursementAmount);
        productGroup.setUpdater(mcStaffRealName);
        productGroup.setUpdateTime(new Date());
        return productGroupDao.updateByKey(productGroup);
    }

    @Override
    public Integer updateStatusBatch(StatusDTO dto) {

        Integer result = productGroupDao.updateStatusBatch(dto);
        sendProductGroupChange(getProductGroupList(dto.getIds()));
        return result;
    }

    /**
     * 描述: 新增数据
     *
     * @param productGroup 待新增数据
     * @return java.lang.Integer 主键key
     * @author tanghongjun
     * @since 2020-08-19 11:18:36
     **/
    @Override
    public Integer insert(ProductGroup productGroup) {

        if (Objects.isNull(productGroup)) {
            log.error("[{}],新增数据,productGroup为null", TAG);
            return null;
        }
        Integer result = productGroupDao.insert(productGroup);
        sendProductGroupChange(getProductGroupList(productGroup));
        return result;
    }

    /**
     * 描述: 根据主键删除数据
     *
     * @param groupId
     * @return: 执行结果码
     * @auther: tanghongjun
     * @since: 2020-08-19 11:18:36
     */
    @Override
    public Integer deleteByKey(Integer groupId) {

        if (Objects.isNull(groupId)) {
            log.error("[{}],根据id删除数据,groupId为null", TAG);
            return null;
        }
        return productGroupDao.deleteByKey(groupId);
    }

    private List<ProductGroupMessage> getProductGroupList(ProductGroup productGroup) {

        List<ProductGroupMessage> list = new ArrayList<>();
        ProductGroupMessage message = ProductGroupMessage.builder()
                .groupId(productGroup.getGroupId())
                .groupCode(productGroup.getGroupCode())
                .name(productGroup.getName())
                .bizType(productGroup.getBizType())
                .status(productGroup.getStatus())
                .build();
        list.add(message);
        return list;
    }

    private List<ProductGroupMessage> getProductGroupList(List<Integer> ids) {

        if (CollectionUtil.isNullOrEmpty(ids)) {
            return new ArrayList<>();
        }
        try {
            List<ProductGroup> productGroupList = listByIdList(ids);
            return productGroupList.stream().map(p -> ProductGroupMessage.builder()
                    .groupId(p.getGroupId())
                    .groupCode(p.getGroupCode())
                    .name(p.getName())
                    .bizType(p.getBizType())
                    .status(p.getStatus())
                    .build()).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("[{}], 产品分组变化发送消息，组装数据异常，ids:{}, msg:{}", TAG, ids, e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 发送产品分组变化
     *
     * @param productGroupList 产品分组MQ消息
     * @author xujie
     * @since 2021/08/19
     */
    private void sendProductGroupChange(List<ProductGroupMessage> productGroupList) {

        if (CollectionUtil.isNullOrEmpty(productGroupList)) {
            return;
        }
        try {
            zmnMQSender.send(topic, MessageQueueConstant.PRODUCT_GROUP_CHANGE_TAG, UUID.randomUUID().toString(), JSONObject.toJSONString(productGroupList));
        } catch (Exception e) {
            log.error("[{}], 产品分组变化发送消息异常, 参数：{}, msg: {}", TAG, JSONObject.toJSONString(productGroupList), e.getMessage(), e);
        }
    }
}